package net.vanchu.mortgagecalculator.mortgage.resultShow;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

import com.dtspread.libs.share.ShareController;
import com.dtspread.libs.share.util.ShareUtil;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

import net.vanchu.mortgagecalculator.common.config.AppConstant;
import net.vanchu.mortgagecalculator.common.config.OptionsProvider;
import net.vanchu.mortgagecalculator.mortgage.data.monthRepayment.MixMonthRepay;
import net.vanchu.mortgagecalculator.mortgage.data.monthRepayment.SingleMonthRepay;
import net.vanchu.mortgagecalculator.mortgage.data.repaymentSummary.PrincipalBalancedPart;
import net.vanchu.mortgagecalculator.mortgage.data.repaymentSummary.RepaySummary;
import net.vanchu.mortgagecalculator.mortgage.data.repaymentSummary.TotalBalancedPart;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * Created by Granton on 2016/12/26.
 */
class ResultShowPresenter implements ResultShowContract.Presenter {

    private static final String TAG = ResultShowPresenter.class.getSimpleName();

    private ResultShowContract.View view;

    private ComplainButtonListener complainButtonListener;

    private RepaySummary.Mix mixRepaySummary;

    private RepaySummary.Single singleRepaySummary;

    ResultShowPresenter(ResultShowContract.View view, ComplainButtonListener complainButtonListener) {
        this.view = view;
        this.complainButtonListener = complainButtonListener;
    }

    @Override
    public void extractData(Intent intent) {
        if (extractSingleLoanWayData(intent)) return;
        extractMixLoanWayData(intent);
    }

    @Override
    public void performSetRemindDate(int date) {

    }

    private static final String TPL_TITLE = "快看！房贷%s万，%s年后竟要还这么多！";
    private static final String TPL_CONTENT = "背负%s年的房贷，要还这么多你知道吗？";

    @Override
    public void shareResult(Activity activity) {
        ShareController shareController = new ShareController(activity, "from");
        String title = generateShareTitle();
        String content = generateShareContent();
        String url = generateShareUrl();
        LoggerResultShow.d(TAG, url);
        ShareUtil.prepareToShare(shareController, title, content, AppConstant.ICON_URL, url);
        shareController.showShareBoard();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        if (singleRepaySummary != null) {
            outState.putSerializable("SINGLE", singleRepaySummary);
            return;
        }
        if (mixRepaySummary != null) {
            outState.putSerializable("MIX", mixRepaySummary);
        }
    }

    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
        singleRepaySummary = (RepaySummary.Single) savedInstanceState.getSerializable("SINGLE");
        mixRepaySummary = (RepaySummary.Mix) savedInstanceState.getSerializable("MIX");
        if (singleRepaySummary != null) {
            passSingleRepaySummaryToView();
            return;
        }
        if (mixRepaySummary != null) {
            passMixRepaySummaryToView();
        }
    }

    private String generateShareUrl() {
        JsonObject jsonObject = new JsonObject();
        if (singleRepaySummary != null) {
            assignSingleRepaySummaryToJson(jsonObject);
        }
        if (mixRepaySummary != null) {
            assignMixRepaySummaryToJson(jsonObject);
        }

        String prefix = AppConstant.URL_SHARE_SIMPLE_LOAN_RESULT;
        if (mixRepaySummary != null) {
            prefix = AppConstant.URL_SHARE_COMBINATION_LOAN_RESULT;
        }
        return prefix + new String(jsonObject.toString().getBytes(), Charset.forName("UTF-8"));
    }

    private void assignMixRepaySummaryToJson(JsonObject jsonObject) {
        jsonObject.addProperty("mode", OptionsProvider.convertLoanWayToStringShow(mixRepaySummary.getLoanWay()));
        jsonObject.addProperty("money", mixRepaySummary.getPrincipal() / 10000);
        jsonObject.addProperty("timeLimit", mixRepaySummary.getNumberOfMonths() / 12);
        jsonObject.addProperty("payMode", "等额本息");
        double payTotal = mixRepaySummary.getTotalBalancedMix().getComPrincipalAndInterest().getTotalRepay()
                + mixRepaySummary.getTotalBalancedMix().getProPrincipalAndInterest().getTotalRepay();
        jsonObject.addProperty("payTotal", FormatHelper.formatDouble(payTotal));
        jsonObject.addProperty("monthPay", FormatHelper.formatDouble(mixRepaySummary.getTotalBalancedMix().getNumberRepayPerMonth()));
        double totalPrice = mixRepaySummary.getTotalBalancedMix().getComPrincipalAndInterest().getInterest() +
                mixRepaySummary.getTotalBalancedMix().getProPrincipalAndInterest().getInterest();
        jsonObject.addProperty("totalPrice", FormatHelper.formatDouble(totalPrice));
        jsonObject.addProperty("commercialLoan", FormatHelper.formatDouble(mixRepaySummary.getTotalBalancedMix().getComPrincipalAndInterest().getTotalRepay()));
        jsonObject.addProperty("accumulationFund", FormatHelper.formatDouble(mixRepaySummary.getTotalBalancedMix().getProPrincipalAndInterest().getTotalRepay()));
        List<MixMonthRepay> mixMonthRepays = mixRepaySummary.getTotalBalancedMix().getMixMonthRepays();
        JsonArray data = new JsonArray();
        data.add(getMonthRepayMixWayData(mixMonthRepays.get(0)));
        data.add(getMonthRepayMixWayData(mixMonthRepays.get(1)));
        data.add(getMonthRepayMixWayData(mixMonthRepays.get(2)));
        data.add(getMonthRepayMixWayData(mixMonthRepays.get(3)));
        data.add(getMonthRepayMixWayData(mixMonthRepays.get(4)));
        data.add(getMonthRepayMixWayData(mixMonthRepays.get(5)));
        jsonObject.add("data", data);
    }

    private JsonArray getMonthRepayMixWayData(MixMonthRepay mixMonthRepay) {
        JsonArray jsonElements = new JsonArray();
        jsonElements.add(mixMonthRepay.getIndex());
        jsonElements.add(mixMonthRepay.getTotalRepayNumber());
        jsonElements.add(mixMonthRepay.getCommercialPart().getTotalRepay());
        jsonElements.add(mixMonthRepay.getProvidentFundPart().getTotalRepay());
        return jsonElements;
    }

    private void assignSingleRepaySummaryToJson(JsonObject jsonObject) {
        jsonObject.addProperty("mode", OptionsProvider.convertLoanWayToStringShow(singleRepaySummary.getLoanWay()));
        jsonObject.addProperty("money", singleRepaySummary.getPrincipal() / 10000);
        jsonObject.addProperty("timeLimit", singleRepaySummary.getNumberOfMonths() / 12);
        jsonObject.addProperty("payMode", "等额本息");
        jsonObject.addProperty("monthPay", FormatHelper.formatDouble(singleRepaySummary.getTotalBalancedPart().getNumberRepayPerMonth()));
        jsonObject.addProperty("totalPrice", FormatHelper.formatDouble(singleRepaySummary.getTotalBalancedPart().getPrincipalAndInterest().getInterest()));
        jsonObject.addProperty("payTotal", FormatHelper.formatDouble(singleRepaySummary.getTotalBalancedPart().getPrincipalAndInterest().getTotalRepay()));
        List<SingleMonthRepay> singleMonthRepays = singleRepaySummary.getTotalBalancedPart().getSingleMonthRepays();
        JsonArray data = new JsonArray();
        data.add(getMonthRepaySingleWayData(singleMonthRepays.get(0)));
        data.add(getMonthRepaySingleWayData(singleMonthRepays.get(1)));
        data.add(getMonthRepaySingleWayData(singleMonthRepays.get(2)));
        data.add(getMonthRepaySingleWayData(singleMonthRepays.get(3)));
        data.add(getMonthRepaySingleWayData(singleMonthRepays.get(4)));
        data.add(getMonthRepaySingleWayData(singleMonthRepays.get(5)));
        jsonObject.add("data", data);
    }

    private JsonArray getMonthRepaySingleWayData(SingleMonthRepay singleMonthRepay) {
        JsonArray jsonElements = new JsonArray();
        jsonElements.add(singleMonthRepay.getIndex());
        jsonElements.add(singleMonthRepay.getTotalRepayNumber());
        jsonElements.add(singleMonthRepay.getTotalPrincipal());
        jsonElements.add(singleMonthRepay.getTotalInterest());
        jsonElements.add(singleMonthRepay.getRemainPrincipal());
        return jsonElements;
    }

    private String generateShareContent() {
        if (mixRepaySummary != null) {
            return String.format(Locale.getDefault(), TPL_CONTENT,
                    String.valueOf(mixRepaySummary.getNumberOfMonths() / 12));
        }
        if (singleRepaySummary != null) {
            return String.format(Locale.getDefault(), TPL_CONTENT,
                    String.valueOf(singleRepaySummary.getNumberOfMonths() / 12));
        }
        return null;
    }

    private String generateShareTitle() {
        if (mixRepaySummary != null) {
            return String.format(Locale.getDefault(), TPL_TITLE,
                    String.valueOf(mixRepaySummary.getPrincipal() / 10000),
                    String.valueOf(mixRepaySummary.getNumberOfMonths() / 12));
        }
        if (singleRepaySummary != null) {
            return String.format(Locale.getDefault(), TPL_TITLE,
                    String.valueOf(singleRepaySummary.getPrincipal() / 10000),
                    String.valueOf(singleRepaySummary.getNumberOfMonths() / 12));
        }
        return null;
    }

    private void extractMixLoanWayData(Intent intent) {
        mixRepaySummary = (RepaySummary.Mix) intent.getSerializableExtra(
                ResultShowContract.MIX_REPAY_SUMMARY_KEY
        );
        if (mixRepaySummary != null) {
            passMixRepaySummaryToView();
        }
    }

    private void passMixRepaySummaryToView() {
        double principalOriginal = mixRepaySummary.getPrincipal();
        showTotalPrincipal(principalOriginal);

        TotalBalancedPart.Mix totalBalancedMix = mixRepaySummary.getTotalBalancedMix();
        double totalRepayLeft = totalBalancedMix.getComPrincipalAndInterest().getTotalRepay() +
                totalBalancedMix.getProPrincipalAndInterest().getTotalRepay();
        String leftTitle = "总额：" + FormatHelper.formatDouble(totalRepayLeft);

        PrincipalBalancedPart.Mix principalBalancedMix = mixRepaySummary.getPrincipalBalancedMix();
        double totalRepayRight = principalBalancedMix.getComPrincipalAndInterest().getTotalRepay() +
                principalBalancedMix.getProPrincipalAndInterest().getTotalRepay();
        String rightTitle = "总额：" + FormatHelper.formatDouble(totalRepayRight);

        MixWayResultDataAdapter[] adapters = createMixLoanWayDataAdapters(mixRepaySummary);
        view.showMixLoanResult(adapters, leftTitle, rightTitle);
    }

    private MixWayResultDataAdapter[] createMixLoanWayDataAdapters(RepaySummary.Mix mixRepaySummary) {
        MixWayResultDataAdapter[] mixWayResultDataAdapters = new MixWayResultDataAdapter[2];
        mixWayResultDataAdapters[0] = createMixTotalBalancedDataAdapter(mixRepaySummary);
        mixWayResultDataAdapters[1] = createMixPrincipalBalancedDataAdapter(mixRepaySummary);
        return mixWayResultDataAdapters;
    }

    private MixWayResultDataAdapter createMixTotalBalancedDataAdapter(RepaySummary.Mix mixRepaySummary) {
        List<ResultData<RepaySummary.Mix>> dataList = new ArrayList<>();
        dataList.add(new ResultData<>(ResultData.ITEM_TYPE_MIX_TOTAL_BALANCED_SUM, mixRepaySummary));
        dataList.add(new ResultData<>(ResultData.ITEM_TYPE_RESULT_SHOW_COMPLAIN, mixRepaySummary));
        dataList.add(new ResultData<>(ResultData.ITEM_TYPE_MIX_TABLE_HEADER, mixRepaySummary));
        int numberOfMonths = mixRepaySummary.getNumberOfMonths();
        for (int i = 0; i < numberOfMonths; i++) {
            if (i % 2 == 0) {
                dataList.add(new ResultData<>(
                        ResultData.ITEM_TYPE_MIX_TOTAL_BALANCED_TABLE_DATA_ODD_INDEX, mixRepaySummary));
            } else {
                dataList.add(new ResultData<>(
                        ResultData.ITEM_TYPE_MIX_TOTAL_BALANCED_TABLE_DATA_EVEN_INDEX, mixRepaySummary));
            }
        }
        dataList.add(new ResultData<>(ResultData.ITEM_TYPE_RESULT_SHOW_FOOTER, mixRepaySummary));
        return new MixWayResultDataAdapter(dataList, complainButtonListener);
    }

    private MixWayResultDataAdapter createMixPrincipalBalancedDataAdapter(RepaySummary.Mix mixRepaySummary) {
        List<ResultData<RepaySummary.Mix>> dataList = new ArrayList<>();
        dataList.add(new ResultData<>(ResultData.ITEM_TYPE_MIX_PRINCIPAL_BALANCED_SUM, mixRepaySummary));
        dataList.add(new ResultData<>(ResultData.ITEM_TYPE_RESULT_SHOW_COMPLAIN, mixRepaySummary));
        dataList.add(new ResultData<>(ResultData.ITEM_TYPE_MIX_TABLE_HEADER, mixRepaySummary));
        int numberOfMonths = mixRepaySummary.getNumberOfMonths();
        for (int i = 0; i < numberOfMonths; i++) {
            if (i % 2 == 0) {
                dataList.add(new ResultData<>(
                        ResultData.ITEM_TYPE_MIX_PRINCIPAL_BALANCED_TABLE_DATA_ODD_INDEX, mixRepaySummary));
            } else {
                dataList.add(new ResultData<>(
                        ResultData.ITEM_TYPE_MIX_PRINCIPAL_BALANCED_TABLE_DATA_EVEN_INDEX, mixRepaySummary));
            }
        }
        dataList.add(new ResultData<>(ResultData.ITEM_TYPE_RESULT_SHOW_FOOTER, mixRepaySummary));
        return new MixWayResultDataAdapter(dataList, complainButtonListener);
    }

    private boolean extractSingleLoanWayData(Intent intent) {
        singleRepaySummary = (RepaySummary.Single) intent.getSerializableExtra(
                ResultShowContract.SINGLE_REPAY_SUMMARY_KEY
        );
        if (singleRepaySummary != null) {
            passSingleRepaySummaryToView();
            return true;
        }
        return false;
    }

    private void passSingleRepaySummaryToView() {
        double principalOriginal = singleRepaySummary.getPrincipal();
        showTotalPrincipal(principalOriginal);

        double totalRepayLeft = singleRepaySummary.getTotalBalancedPart().getPrincipalAndInterest().getTotalRepay();
        double totalRepayRight = singleRepaySummary.getPrincipalBalancedPart().getPrincipalAndInterest().getTotalRepay();
        String leftStr = "总额：" + FormatHelper.formatDouble(totalRepayLeft);
        String rightStr = "总额：" + FormatHelper.formatDouble(totalRepayRight);

        SingleWayResultDataAdapter[] dataAdapters = createSingleLoanWayDataAdapters(singleRepaySummary);
        view.showSingleLoanResult(dataAdapters, leftStr, rightStr);
    }

    private SingleWayResultDataAdapter[] createSingleLoanWayDataAdapters(RepaySummary.Single singleRepaySummary) {
        SingleWayResultDataAdapter[] singleLoanWayPageAdapters = new SingleWayResultDataAdapter[2];
        singleLoanWayPageAdapters[0] = createSingleTotalBalancedDataAdapter(singleRepaySummary);
        singleLoanWayPageAdapters[1] = createSinglePrincipalBalancedDataAdapter(singleRepaySummary);
        return singleLoanWayPageAdapters;
    }

    private SingleWayResultDataAdapter createSingleTotalBalancedDataAdapter(RepaySummary.Single singleRepaySummary) {
        List<ResultData<RepaySummary.Single>> dataList = new ArrayList<>();
        dataList.add(new ResultData<>(ResultData.ITEM_TYPE_SINGLE_TOTAL_BALANCED_SUM, singleRepaySummary));
        dataList.add(new ResultData<>(ResultData.ITEM_TYPE_RESULT_SHOW_COMPLAIN, singleRepaySummary));
        dataList.add(new ResultData<>(ResultData.ITEM_TYPE_SINGLE_TABLE_HEADER, singleRepaySummary));
        List<SingleMonthRepay> singleMonthRepays = singleRepaySummary.getTotalBalancedPart().getSingleMonthRepays();
        int size = singleMonthRepays.size();
        for (int i = 0; i < size; i++) {
            if (i % 2 == 0) {
                dataList.add(new ResultData<>(
                        ResultData.ITEM_TYPE_SINGLE_TOTAL_BALANCED_TABLE_DATA_ODD_INDEX, singleRepaySummary));
            } else {
                dataList.add(new ResultData<>(
                        ResultData.ITEM_TYPE_SINGLE_TOTAL_BALANCED_TABLE_DATA_EVEN_INDEX, singleRepaySummary));
            }
        }
        dataList.add(new ResultData<>(ResultData.ITEM_TYPE_RESULT_SHOW_FOOTER, singleRepaySummary));
        return new SingleWayResultDataAdapter(dataList, complainButtonListener);
    }

    private SingleWayResultDataAdapter createSinglePrincipalBalancedDataAdapter(RepaySummary.Single singleRepaySummary) {
        List<ResultData<RepaySummary.Single>> dataList = new ArrayList<>();
        dataList.add(new ResultData<>(ResultData.ITEM_TYPE_SINGLE_PRINCIPAL_BALANCED_SUM, singleRepaySummary));
        dataList.add(new ResultData<>(ResultData.ITEM_TYPE_RESULT_SHOW_COMPLAIN, singleRepaySummary));
        dataList.add(new ResultData<>(ResultData.ITEM_TYPE_SINGLE_TABLE_HEADER, singleRepaySummary));
        int numberOfMonths = singleRepaySummary.getNumberOfMonths();
        for (int i = 0; i < numberOfMonths; i++) {
            if (i % 2 == 0) {
                dataList.add(new ResultData<>(
                        ResultData.ITEM_TYPE_SINGLE_PRINCIPAL_BALANCED_TABLE_DATA_ODD_INDEX, singleRepaySummary));
            } else {
                dataList.add(new ResultData<>(
                        ResultData.ITEM_TYPE_SINGLE_PRINCIPAL_BALANCED_TABLE_DATA_EVEN_INDEX, singleRepaySummary));
            }
        }
        dataList.add(new ResultData<>(ResultData.ITEM_TYPE_RESULT_SHOW_FOOTER, singleRepaySummary));
        return new SingleWayResultDataAdapter(dataList, complainButtonListener);
    }

    private void showTotalPrincipal(double principalOriginal) {
        double principal = principalOriginal / 10000;
        String principalStrToShow = "贷款" + principal + "万元";
        view.showTotalPrincipal(principalStrToShow);
    }
}